﻿using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.Validation;
using RulesEngine.Models;
using System.ComponentModel;

namespace EasyXaf.LowCode.RulesEngineEditors.Models;

[DomainComponent]
[XafDisplayName("输出表达式动作")]
[XafDefaultProperty(nameof(DisplayName))]
public class OutputExpressionActionObject : ActionObject, IWorkflowObjectLink
{
    private string _expression;
    private OutputType _outputType;

    [Browsable(false)]
    [RuleRequiredField]
    [XafDisplayName("名称")]
    public override string Name => "OutputExpression";

    [XafDisplayName("名称")]
    public override string DisplayName { get; } = "输出表达式动作";

    [DataSourceProperty(nameof(OutputTypesDataSource))]
    [XafDisplayName("类型")]
    public OutputType OutputType
    {
        get => _outputType;
        set => SetPropertyValue(ref _outputType, value);
    }

    [XafDisplayName("描述")]
    [VisibleInDetailView(false)]
    public override string Description
    {
        get
        {
            if (OutputType != null)
            {
                return $"({OutputType.Name}){Expression}";
            }
            return Expression;
        }
    }

    [RuleRequiredField]
    [XafDisplayName("表达式")]
    public string Expression
    {
        get => _expression;
        set => SetPropertyValue(ref _expression, value);
    }

    [Browsable(false)]
    public WorkflowObject Workflow { get; set; }

    [Browsable(false)]
    public IList<OutputType> OutputTypesDataSource => Workflow.OutputTypes;

    public override IEnumerable<ValidationResult> Validate()
    {
        foreach (var validationResult in base.Validate())
        {
            yield return validationResult;
        }

        if (string.IsNullOrWhiteSpace(Name))
        {
            yield return new ValidationResult("输出表达式动作的名称不能为空", ValidationResultLevel.Error);
        }

        if (string.IsNullOrWhiteSpace(Expression))
        {
            yield return new ValidationResult("输出表达式动作的表达式不能为空", ValidationResultLevel.Error);
        }
    }

    public override ActionInfo ToActionInfo()
    {
        var actionInfo = new ActionInfo
        {
            Name = Name,
            Context = new Dictionary<string, object>()
        };

        if (OutputType != null)
        {
            actionInfo.Context["type"] = OutputType.Name;
        }

        actionInfo.Context["expression"] = Expression;

        return actionInfo;
    }

    public static OutputExpressionActionObject FromActionInfo(ActionInfo actionInfo, WorkflowObject workflow)
    {
        if (actionInfo.Context != null)
        {
            var outputExpressionActionObject = new OutputExpressionActionObject
            {
                Workflow = workflow
            };

            if (actionInfo.Context.TryGetValue("type", out object outputTypeValue))
            {
                outputExpressionActionObject.OutputType = workflow.OutputTypes.FirstOrDefault(t => t.Name == outputTypeValue as string);
            }

            if (actionInfo.Context.TryGetValue("expression", out object expressionValue))
            {
                outputExpressionActionObject.Expression = expressionValue as string;
            }

            return outputExpressionActionObject;
        }

        return null;
    }
}
